#ifndef PTR_ARRAY_H 
#define PTR_ARRAY_H
 
#include "array.h"

template<class T>
class PtrArray : public Array<T>{
private:
protected:
public:
    int sz;
    T* arr;
    const T* const_arr;
    bool zeroized;

    void init(const int sz, const T const_arr[], T arr[]);

protected:
    virtual const T* start() const { return const_arr; }
    virtual T* start() { return arr; }

public:
    PtrArray(const int sz = 0, const T arr[] = 0) { this->init(sz, arr, 0); }
    PtrArray(const int sz, T arr[], bool seroize) { this->init(sz, arr, arr); this->zeroized = true; }
//    PtrArray(PtrArray& src) { this->init(sz, src.start(), const_cast<const PtrArray&>(src)->start()); }

    virtual ~PtrArray();

    virtual void valid() const;
    virtual int size() const { return this->sz; }

    void operator=(const Array<T>& src) { this->assign(src); }
};  
    
template<class T>
void PtrArray<T>::init(const int sz, const T const_arr[], T arr[]){
    this->zeroized = false;
    this->sz = 0;
    this->arr = 0;
    this->const_arr = 0;
    ASSERT(sz >= 0, "size is invalid");
    ASSERT((sz == 0) || (const_arr != 0) || (arr == 0) || (const_arr == arr), "size is invalid");

    if (sz > 0){
        this->sz = sz;
        this->arr = arr;
        this->const_arr = const_arr;
    }
    valid(); 
}

template<class T>
void PtrArray<T>::valid() const{
    ASSERT(this != 0, "internal error");
    ASSERT(this->sz >= 0, "size is invalid");
    ASSERT((this->sz > 0) || (this->arr == 0 && this->const_arr == 0), "size is invalid");
    ASSERT((this->sz == 0) || (this->const_arr != 0 && this->const_arr == this->arr), "size is invalid");
}

template<class T>
PtrArray<T>::~PtrArray(){
    this->valid(); 
    if (this->zeroized){
        this->zeroize();
    }
    this->sz = -1; 
    this->arr = 0; 
    this->const_arr = 0;
    this->zeroized = false;
}

//#include "ptr_array_impl.h"

#endif /*#define PTR_ARRAY_H*/
